#include "str.h"

#include "mem.h"

#include <assert.h>
#include <string.h>

static void
test_case1()
{
    const char *str = "hello, world";
    char *p;
    p = Str_sub(str, 1, 0);
    assert(strcmp(p, str) == 0);
    FREE(p);

    p = Str_sub(str, 0, -5);
    assert(strcmp(p, "world") == 0);
    FREE(p);

    p = Str_dup(str, 1, 0, 2); 
    assert(strcmp(p, "hello, worldhello, world") == 0);
    FREE(p);

    const char *str2 = " abc";
    p = Str_cat(str, 1, 0, str2, 1, 0);
    assert(strcmp(p, "hello, world abc") == 0);
    FREE(p);

    p = Str_catv(str, 1, 0, str2, 1, 0, NULL);
    assert(strcmp(p, "hello, world abc") == 0);
    FREE(p);

    p = Str_reverse(str, 0, -5);
    assert(strcmp(p, "dlrow") == 0);
    FREE(p);

    p = Str_map(str, 0, -5, "world", "WORLD");
    assert(strcmp(p, "WORLD") == 0);
    FREE(p);

    int ret;
    ret = Str_pos(str, 0);
    assert(ret == (int)strlen(str)+1);
    ret = Str_pos(str, -1);
    assert(ret == (int)strlen(str));

    ret = Str_len(str, 0, 1);
    assert(ret == (int)strlen(str));

    assert(Str_cmp(str, 0, -5, "world", 1, 0) == 0);

    Fmt_register('a', Str_fmt);
    p = Fmt_string("%a", str, 1, 6);
    assert(strcmp(p, "hello") == 0);
    FREE(p);
}

static void
test_case2()
{
    const char *str = "hello, world";
    assert(Str_chr(str, 1, 0, 'z') == 0);
    assert(Str_chr(str, 1, 0, 'l') == 3);

    assert(Str_rchr(str, 1, 0, 'z') == 0);
    assert(Str_rchr(str, 1, 0, 'l') == 11);

    assert(Str_upto(str, 1, 0, "xyz") == 0);
    assert(Str_upto(str, 1, 0, "xyzl") == 3);

    assert(Str_rupto(str, 1, 0, "xyz") == 0);
    assert(Str_rupto(str, 1, 0, "xyzl") == 11);

    assert(Str_find(str, 1, 0, "HELLO") == 0);
    assert(Str_find(str, 1, 0, "hello") == 1);

    assert(Str_rfind(str, 1, 0, "HELLO") == 0);
    assert(Str_rfind(str, 1, 0, "hello") == 1);
}

static void
test_case3()
{
    const char *str = "hello, world";
    assert(Str_any(str, 1, "h") == 2);
    assert(Str_any(str, 1, "H") == 0);
    assert(Str_any(str, 1, "Hh") == 2);

    assert(Str_many(str, 1, 0, "h-ello") == 6);
    assert(Str_many(str, 1, 0, "z") == 0);

    assert(Str_rmany(str, 1, 0, "w-orld") == 8);
    assert(Str_rmany(str, 1, 0, "z") == 0);

    assert(Str_match(str, 1, 6, "hello") == 6);
    assert(Str_match(str, 1, 6, "z") == 0);

    assert(Str_rmatch(str, -5, 0, "world") == 8);
    assert(Str_rmatch(str, -5, 0, "z") == 0);
}

static char*
basename(char *path, int i, int j, const char *suffix)
{
    i = Str_rchr(path, i, j, '/');
    j = Str_rmatch(path, i+1, 0, suffix);
    return Str_dup(path, i+1, j, 1);
}

static void
test_basename()
{
    char *p;
    p = basename("/usr/jenny/main.c", 1, 0, ".c");
    assert(strcmp(p, "main") == 0);
    FREE(p);

    p = basename("../src/main.c", 1, 0, "");
    assert(strcmp(p, "main.c") == 0);
    FREE(p);

    p = basename("main.c", 1, 0, ".obj");
    assert(strcmp(p, "main.c") == 0);
    FREE(p);

    p = basename("examples/wfmain.c", 1, 0, "main.c");
    assert(strcmp(p, "wf") == 0);
    FREE(p);
}

int main()
{
    test_case1();
    test_case2();
    test_case3();
    test_basename();
    return 0;
}

